package com.example.test15middleware.config;

import com.example.test15middleware.util.JsonSerializeUtil;
import org.redisson.api.RLock;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Service
public class RedissonService {

    @Resource
    private RedissonClient redissonClient;


    //发布
    public <T> long publish(String topic, T t) {
        RTopic rTopic = redissonClient.getTopic(topic);
        return rTopic.publish(JsonSerializeUtil.jsonSerializerNoType(t));
    }


    public <T> void publishAsync(String topic, T t) {
        RTopic rTopic = redissonClient.getTopic(topic);
        rTopic.publishAsync(JsonSerializeUtil.jsonSerializerNoType(t));
    }

/*    // 订阅
    public <T> void subscribe(String topic, Class<T> returnClass, RedissonSubscribeProcess<T> redissonSubscribeProcess) {
        RTopic rTopic = redissonClient.getTopic(topic);

        rTopic.addListener(String.class, new MessageListener<String>() {
            @Override
            public void onMessage(CharSequence charSequence, String subscribeStr) {
                redissonSubscribeProcess.process(JsonSerializeUtil.jsonReSerializerNoType(subscribeStr, returnClass));
            }
        });
    }*/


    /**
     * 加锁
     *
     * @param lockKey
     * @return
     */
    public RLock lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
        return lock;
    }

    /**
     * 释放锁
     *
     * @param lockKey
     */
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }

    /**
     * 释放锁
     *
     * @param lock
     */
    public static void unlock(RLock lock) {
        lock.unlock();
    }

    /**
     * 带超时的锁
     *
     * @param lockKey
     * @param timeoutSeconds 超时时间   单位：秒
     */
    public RLock lock(String lockKey, int timeoutSeconds) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeoutSeconds, TimeUnit.SECONDS);
        return lock;
    }

    /**
     * 带超时的锁
     *
     * @param lockKey
     * @param unit    时间单位
     * @param timeout 超时时间
     */
    public RLock lock(String lockKey, TimeUnit unit, int timeout) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, unit);
        return lock;
    }

    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @param waitTimeSeconds  最多等待时间
     * @param leaseTimeSeconds 上锁后自动释放锁时间
     */
    public boolean tryLock(String lockKey, int waitTimeSeconds, int leaseTimeSeconds) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTimeSeconds, leaseTimeSeconds, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            return false;
        }
    }

    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @param unit      时间单位
     * @param waitTime  最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     */
    public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
            return false;
        }
    }
}
